/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package calcul;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import vue.ObjetEchange;

/**
 *
 * @author Jo
 */
public class MonteCarloMulti extends MonteCarloAbstract{

    @Override
    double MonteCarloStandardOption(String CallPutFlag, double S, double X, double T, 
            double r, double b, double v, int nSteps, int nSimulations) 
    {
        double dt, Sum=0, Drift, vSqrdt;
        int i, j, z=0;
        
        dt = T / nSteps;
        Drift = (b - java.lang.Math.pow(v, 2) / 2) * dt;
        vSqrdt = v * java.lang.Math.sqrt(dt);
        if (CallPutFlag.equals("c")) {
            z = 1;
        }
        else if (CallPutFlag.equals("p")) {
            z = -1;
        }
        for(i = 1; i<= nSimulations; i++){
            //setChanged();
            //notifyObservers(new ObjetEchange(res, false, (float)i/nSimulations));
            
            double St = S;
            //---
            final int numberOfCores = Runtime.getRuntime().availableProcessors();
            final double blockingCoefficient = 0.9;
            final int poolSize = (int)(numberOfCores / (1 - blockingCoefficient));
            
            final List<Callable<Double>> partitions = new ArrayList<Callable<Double>>();
            
            for(j = 1; j<= nSteps; j++) {
            partitions.add(new Callable<Double>() {
                @Override
                public Double call() throws Exception {
                    doCall();
                    return 0.0;
                }
                synchronized void doCall(){
                    
                }
                });
            }
            //---
            for(j = 1; j<= nSteps; j++){
                St = St * java.lang.Math.exp( Drift + vSqrdt * new java.util.Random().nextGaussian() );
            }
            Sum = Sum + java.lang.Math.max(z*(St - X),0);
        }
        return java.lang.Math.exp(-r * T) * (Sum /nSimulations);
    }
    
}
